package com.source.hotelbath.weight.listview.ptr.ptrloadmore;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.AbsListView;
import android.widget.RelativeLayout;


import com.source.hotelbath.R;
import com.source.hotelbath.weight.listview.ptr.PtrDefHeader;
import com.source.hotelbath.weight.listview.ptr.PtrHeaderBase;

import in.srain.cube.views.ptr.PtrDefaultHandler;
import in.srain.cube.views.ptr.PtrFrameLayout;
import in.srain.cube.views.ptr.PtrHandler;

/**
 * 自定义属性
 * content_bkg：下拉的contentview 的背景，如果是listview 则是这是listview的背景，
 * 默认contentview 背景是透明跟随PtrLoadMoreListView的bkg
 * empty_layout：是当进入界面时界面数据位空的时候的界面
 * footer_layout：是加载更多滑到底端是的界面
 * Created by kinglong on 15-6-4.
 */
public abstract class PtrLoadMoreBase<T extends AbsListView> extends RelativeLayout implements PtrLoadMoreBaseInterface<T> {

    private final String TAG=PtrLoadMoreBase.class.getSimpleName();
    protected PtrFrameLayout mPtrFrame;
    protected PtrHeaderBase mHeader;

    protected RelativeLayout mRlContent;

    protected RelativeLayout mEmptyViewContainer;

    protected T mAbsListView;
    /**
     * 检查是否可下拉刷新的view
     */
    protected View mCheckPtrView;
    protected AbsListView.OnScrollListener mScrollListener;
    protected LoadingListener mLoadingListener;

    //protected View mFooterViewContent;
    protected View mFooterView;

    protected int mContentBkgId;
    protected int mFooterLayoutId;
    protected int mEmptyLayoutId;

    protected int mPageSize = 15;
    protected int mPageIndex = 0;
    protected boolean mHasNext;         //是否显示底部item
    protected boolean isLoading;      //是否正在加载
    protected boolean mIsReady;

    public PtrLoadMoreBase(Context context) {
        super(context);
        LayoutInflater.from(context).inflate(R.layout.ptr_base, this, true);
        mPtrFrame = (PtrFrameLayout) findViewById(R.id.ptr_frame);
        mEmptyViewContainer = (RelativeLayout) findViewById(R.id.rl_empty_container);
        mRlContent = (RelativeLayout) findViewById(R.id.rl_content);
        setRefresh();
        setEmptyView(R.layout.ptr_listview_empty);
        getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                // TODO Auto-generated method stub
                mIsReady = true;
            }
        });
    }

    public PtrLoadMoreBase(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.ptr_base, this, true);
        mPtrFrame = (PtrFrameLayout) findViewById(R.id.ptr_frame);
        mEmptyViewContainer = (RelativeLayout) findViewById(R.id.rl_empty_container);
        mRlContent = (RelativeLayout) findViewById(R.id.rl_content);

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ptr);
        mContentBkgId = typedArray.getResourceId(R.styleable.ptr_content_bkg, -1);
        mFooterLayoutId = typedArray.getResourceId(R.styleable.ptr_footer_layout, -1);
        mEmptyLayoutId = typedArray.getResourceId(R.styleable.ptr_empty_layout, -1);
        if (mContentBkgId != -1)
            mRlContent.setBackgroundResource(mContentBkgId);

        setRefresh();
        if (-1 != mEmptyLayoutId) {
            setEmptyView(mEmptyLayoutId);
        } else {
            setEmptyView(R.layout.ptr_listview_empty);
        }

        getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                // TODO Auto-generated method stub
                mIsReady = true;
            }
        });

    }


    /**
     * 设置下拉刷新的参数，监听
     */
    private void setRefresh() {
        mHeader = new PtrDefHeader(getContext());
        mPtrFrame.setHeaderView(mHeader);
        mPtrFrame.addPtrUIHandler(mHeader);
        mPtrFrame.setPtrHandler(new PtrHandler() {
            @Override
            public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {
                // here check $mListView instead of $content
                if (mCheckPtrView != null) {
                    return PtrDefaultHandler.checkContentCanBePulledDown(frame, mCheckPtrView, header);
                } else if (null != mAbsListView) {
                    return PtrDefaultHandler.checkContentCanBePulledDown(frame, mAbsListView, header);
                } else {
                    Log.e("ptr error", "you have no view to pulltorefresh");
                    return false;
                }
            }

            @Override
            public void onRefreshBegin(PtrFrameLayout frame) {
                mPageIndex = 0;
                if (null != mLoadingListener) {
                    setHasNext(false);
                    isLoading = true;
                    mLoadingListener.refresh(mPageIndex, mPageSize);  //一直在刷新的过程

                }else{
                    mPtrFrame.refreshComplete();
                }
            }
        });
    }

    @Override
    public <K extends PtrHeaderBase> void setHeader(K header) {
        mPtrFrame.setHeaderView(header);
        mPtrFrame.addPtrUIHandler(header);
        mHeader = header;
    }


    /**
     * 设置显示上次更新的spf 对应的key，一个应用可能存在多个下拉刷新，key需要分开存储，
     * 如果不设置或者设置为空，则下拉的时候不会显示上次更新的时间
     *
     * @param value
     */
    public void setLastUpdateKey(String value) {
        mHeader.setLastUpdateTimeKey(value);
    }


    @Override
    public void autoRefresh() {
        if (!mIsReady) {
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    autoRefresh();
                }
            }, 200);
        }else{
            mPtrFrame.autoRefresh();
            if (mPtrFrame.isAutoRefresh()&&mAbsListView.getChildCount() > 0) {
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mAbsListView.setSelection(0);
                    }
                },200);
            }
        }
    }


    @Override
    public void loadSuccess() {
        mPageIndex++;
        showContentView();
        mPtrFrame.refreshComplete();
        isLoading = false;

    }

    @Override
    public void loadFailure() {
        mPtrFrame.refreshComplete();
        isLoading = false;

    }

    @Override
    public void loadFailure(boolean value) {
        loadFailure();
        if (value) {
            showEmptyView();
        }
    }

    @Override
    public void setHasNext(boolean value) {
        this.mHasNext = value;
        if (mHasNext) {
            if (mFooterView instanceof ViewGroup) {
                ViewGroup vg = (ViewGroup) mFooterView;
                for (int i = 0; i < vg.getChildCount(); i++) {
                    vg.getChildAt(i).setVisibility(View.VISIBLE);
                }
            } else {
                mFooterView.setVisibility(View.VISIBLE);
            }
        } else {
            if (mFooterView instanceof ViewGroup) {
                ViewGroup vg = (ViewGroup) mFooterView;
                for (int i = 0; i < vg.getChildCount(); i++) {
                    vg.getChildAt(i).setVisibility(View.GONE);
                }
            } else {
                mFooterView.setVisibility(View.GONE);
            }
        }
    }

    @Override
    public void setEmptyView(View view) {
        mEmptyViewContainer.removeAllViews();
        mEmptyViewContainer.addView(view);
    }

    @Override
    public void setEmptyView(int id) {
        View view = LayoutInflater.from(getContext()).inflate(id, null);
        mEmptyViewContainer.removeAllViews();
        mEmptyViewContainer.addView(view);
    }

    @Override
    public View getEmptyView() {
        if (mEmptyViewContainer.getChildCount() > 0) {
            return mEmptyViewContainer.getChildAt(0);
        } else {
            return null;
        }
    }


    @Override
    public void setRefreshView(T view) {
        if (view.getParent() != null && view.getParent() instanceof ViewGroup) {
            ViewGroup viewGroup = (ViewGroup) view.getParent();
            viewGroup.removeView(view);
        }
        mRlContent.addView(view);
        mAbsListView = view;
        setFooterView();
        setDefScroll();
        showEmptyView();
    }


    @Override
    public void setOnScrollListener(final AbsListView.OnScrollListener onScrollListener) {
        mAbsListView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView absListView, int scrollState) {
                onScrollListener.onScrollStateChanged(absListView, scrollState);
                mScrollListener.onScrollStateChanged(absListView, scrollState);
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                onScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
                mScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);

            }
        });
    }

    private void setDefScroll() {
        mScrollListener = new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView absListView, int scrollState) {
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if (!isLoading && mHasNext) {
                    if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0) {
                        if (null != mLoadingListener) {
                            mLoadingListener.loadMore(mPageIndex, mPageSize);
                            isLoading = true;
                        }
                    }
                }
            }
        };
        mAbsListView.setOnScrollListener(mScrollListener);
    }


    @Override
    public void showEmptyView() {
        if (mEmptyViewContainer.getVisibility() != View.VISIBLE) {
            mEmptyViewContainer.setVisibility(View.VISIBLE);
        }
        if (mAbsListView.getVisibility() != View.GONE) {
            mAbsListView.setVisibility(View.GONE);
        }
    }

    @Override
    public void showContentView() {
        if (mEmptyViewContainer.getVisibility() != View.GONE) {
            mEmptyViewContainer.setVisibility(View.GONE);
        }
        if (mAbsListView.getVisibility() != View.VISIBLE) {
            mAbsListView.setVisibility(View.VISIBLE);
        }
    }


    @Override
    public T getRefreshView() {
        return mAbsListView;
    }

    @Override
    public int getPageIndex() {
        return mPageIndex;
    }

    @Override
    public void setPageSize(int pageSize) {

        mPageSize = pageSize;
    }

    @Override
    public int getPageSize() {
        return mPageSize;
    }

    @Override
    public boolean hasNext() {
        return mHasNext;
    }

    public PtrFrameLayout getPtrFrame() {
        return mPtrFrame;
    }

    /**
     * 加载的监听，refresh是下拉，lading是滑到底部，本来是将这两个方法合在一起，
     * 为了在某些不分页的情况下也使用下拉刷新
     * （比如历史记录还要继续显示的情况，下拉刷新后将新纪录加到旧记录前面即可），
     * 滑到底部加载更多，将refresh和loading分开
     */
    public interface LoadingListener {
        /**
         * 下拉刷新，有分页功能,
         * 如果不需要使用此分页功能pageIndex，pageSize可以不用处理这两个变量
         *
         * @param pageIndex
         * @param pageSize
         */
        public void refresh(int pageIndex, int pageSize);

        /**
         * 滑到底部加载更多，有分页功能
         * 如果不需要使用此分页共能pageIndex，pageSize可以不用处理这两个变量
         *
         * @param pageIndex
         * @param pageSize
         */
        public void loadMore(int pageIndex, int pageSize);

    }

    public void setCheckPtrView(View checkPtrView) {
        this.mCheckPtrView = checkPtrView;
    }

    public void registListener(LoadingListener loadingListener) {
        mLoadingListener = loadingListener;

    }


    @Override
    public void disableWhenHorizontalMove(boolean value) {
        mPtrFrame.disableWhenHorizontalMove(value);
    }
}
